package com.itbaizhan;
/*所谓 SQL 注入，就是通过把含有 SQL 语句片段的参数插入到需要执行的
 SQL 语句中，最终达到欺骗数据库服务器执行恶意操作的 SQL 命令。*/
/*Statement会有SQL注入的风险
* PreparedStatement 解决了SQL注入风险*/

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

/**Sql 注入测试类*/
public class SqlInjectTest {
    /*体现SQL注入*/
    public void sqlInject(String username,int userage){
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try{
            //获取Connection对象  连接sql
            connection = JdbcUtils.getConnection();
            //获取Statement对象
            statement = connection.createStatement();
            //定义sql语句  userage 是整型，不用加''
            String sql = "select * from users where username = '"+username+"' and userage = "+userage;
            //执行sql语句
            resultSet = statement.executeQuery(sql);
            while(resultSet.next()){
                int userid = resultSet.getInt("userid");
               //因为传入来是username，所以不可以命名为username,变量占用了
                String name = resultSet.getString("username");
                int age = resultSet.getInt("userage");
                System.out.println(userid +" "+name+" "+age );
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.closeResource(resultSet,statement,connection);
        }
    }

    //没有SQL注入
    public void noSqlInject(String username,int userage){
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        try{
            connection = JdbcUtils.getConnection();
            ps = connection.prepareStatement("select * from users where username = ? and userage =  ?");
            ps.setString(1,username);
            ps.setInt(2,userage);
            //执行查询
            resultSet = ps.executeQuery();
            while (resultSet.next()){
                int userid = resultSet.getInt("userid");
                String name = resultSet.getString("username");
                int age = resultSet.getInt("userage");
                System.out.println(userid+ " "+name+" "+age);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.closeResource(resultSet,ps,connection);
        }
    }


    public static void main(String[] args) {
        SqlInjectTest si = new SqlInjectTest();
       // si.sqlInject("hai",33);
        //把含有sql片段的语句放入了参数中运行，会有SQL注入 ，下面的结果是得到了所有数据
        //因为Statement对象会把sql语句与sql绑定的参数一起交给数据库编译器
        //String 类型是在java中才有，数据库中没有的，数据库驱动会把String类型
        // 的编译成一数据库可以编译的类型
        /*Statement把sql语句与sql绑定的参数一起交给数据库编译，造成SQL注入*/
        //si.sqlInject("hai' or 1=1 -- ",33);

        //PreparedStatement 没有SQL注入
        /*因为数据库驱动会先编译sql语句，再把参数传入已编译好的SQL语句，
        *所以参数没有编译 */
        si.noSqlInject("hai‘ or 1=1 -- ",33);//没有结果
    }
}
